using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace Core.Graphics.Layers
{
    [Serializable()]
    [DefaultPropertyAttribute("TileLayer")]
    [XmlRoot("TileLayer")]
    public class TileLayer : Layer, IXmlSerializable
    {
        public TileCollection Tiles { get; set; }

        public TileLayer(TileCollection Tiles, int Width, int Height)
        {
            this.Tiles = Tiles;
            this.Width = Width;
            this.Height = Height;
        }

        public TileLayer(int Width, int Height)
        {
            Tiles = TileCollection.GetTilesForEmptyTileLayer(Width, Height);
            this.Width = Width;
            this.Height = Height;
        }

        public TileLayer() { /*XML Serialization*/ }

        public virtual Tile GetTileAtLocation(int x, int y)
        {
            if (x >= 0 && y >= 0)
                return Tiles[y * Height + x];
            else
                return Tile.BlankTile;
        }

        public virtual void SetTileAtLocation(Tile tile, int x, int y)
        {
            if (x >= 0 && y >= 0)
                Tiles[y * Height + x] = tile;
        }

        #region IXmlSerializable Members

        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            //Read in basic properties
            Name = reader.GetAttribute("Name");
            ZIndex = Convert.ToInt32(reader.GetAttribute("ZIndex"));
            Visible = Convert.ToBoolean(reader.GetAttribute("Visible"));
            Width = Convert.ToInt32(reader.GetAttribute("Width"));
            Height = Convert.ToInt32(reader.GetAttribute("Height"));
            //Create TileCollection
            Tiles = new TileCollection();
            //Read Tile String
            string strAllTiles = reader.GetAttribute("Tiles");


            //load tiles
            if (strAllTiles == "")
            {
                for(int i = 0; i < Width * Height; i++)
                {
                    Tiles.Add(Tile.BlankTile);
                }
            }
            else
            {
                char[] ch = new char[1];
                ch[0] = ',';

                string[] strTiles = strAllTiles.Split(ch);

                foreach (string str in strTiles)
                {
                    //if empty string then add blank tile
                    if (str == "")
                    {
                        Tiles.Add(Tile.BlankTile);
                    }
                    else
                    {                        
                        Tiles.Add(Tile.GetTileFromBitVector(Convert.ToInt32(str)));
                    }
                }
            }
        }

        public void WriteXml(XmlWriter writer)
        {
            //Write Properties to xml
            writer.WriteAttributeString("Name", Name);
            writer.WriteAttributeString("ZIndex", ZIndex.ToString());
            writer.WriteAttributeString("Visible", Visible.ToString());
            writer.WriteAttributeString("Width", Width.ToString());
            writer.WriteAttributeString("Height", Height.ToString());

            //Write Tile Info
            int notblank = 0;

            StringBuilder sb = new StringBuilder();

            foreach (Tile t in Tiles)
            {
                if (t == Tile.BlankTile)
                {
                    //If this tile is empty add a ',' to let us know
                    sb.Append(',');
                }
                else
                {
                    //If this is a real tile save it as "(SpriteID-TileSetID),"  Note trailing ','.  This is necessary for easy use.
                    sb.Append(Tile.GetTileAsBitVector(t).ToString() + ",");
                    //If this tile is not blank add one.
                    notblank++;
                }
            }

            if (notblank == 0)
            {
                //If there were no tiles in whole layer save empty string
                sb = new StringBuilder(string.Empty);
            }

            writer.WriteAttributeString("Tiles", sb.ToString());
        }

        #endregion
    }
}
